package cbh.tool.scheduler.core;

import cbh.tool.StringsVerifyWithRegex;
import cbh.tool.scheduler.*;
import cbh.tool.scheduler.clietn.HttpClientTemplate;
import cbh.tool.scheduler.clietn.HttpType;
import org.apache.http.client.methods.*;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;

import java.io.IOException;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.concurrent.ScheduledExecutorService;

/**
 * Created by hx-pc on 16-4-5.
 */
public class RestTaskExecute implements TaskExecute, CronExpressionAnalyzer {

    private ScheduledExecutorService executorService = ProcessFactory.getScheduledExecutorService();

    public static RestTaskExecute build() {
        return new RestTaskExecute();
    }

    @Override
    public void executeHttpType(HttpType httpType, String host, String uri, String cronExpression, Object... objects) {
        if (httpType == HttpType.GET) {
            executeGet(host, uri, cronExpression, objects);
        } else if (httpType == HttpType.POST) {
            executePost(host, uri, cronExpression, objects);
        } else if (httpType == HttpType.PUT) {
            executePut(host, uri, cronExpression, objects);
        } else if (httpType == HttpType.DELETE) {
            executeDelete(host, uri, cronExpression, objects);
        } else {
            throw new NoSuchHttpType();
        }
    }

    @Override
    public void executeGet(String host, String uri, String cronExpression, Object... objects) {
        HttpGet get = new HttpGet(host + uri);
        executorService.execute(() -> execute(get, buildParam(objects)));
    }

    @Override
    public void executePost(String host, String uri, String cronExpression, Object... objects) {
        HttpPost post = new HttpPost(host + uri);
        executorService.execute(() -> execute(post, buildParam(objects)));
    }

    @Override
    public void executePut(String host, String uri, String cronExpression, Object... objects) {
        HttpPut put = new HttpPut(host + uri);
        executorService.execute(() -> execute(put, buildParam(objects)));
    }

    @Override
    public void executeDelete(String host, String uri, String cronExpression, Object... objects) {
        HttpDelete delete = new HttpDelete(host + uri);
        executorService.execute(() -> execute(delete, buildParam(objects)));
    }

    private HttpContext buildParam(Object... objects) {
        HttpContext httpContext = new BasicHttpContext();
        for (Object o : objects) {
            httpContext.setAttribute(o.getClass().getName(), o);
        }
        return httpContext;
    }

    private void execute(HttpUriRequest uriRequest, HttpContext context) {
        try {
            HttpClientTemplate.getHttpClient().execute(uriRequest, context);
        } catch ( IOException e ) {
            throw new RestTaskExecuteException("Rest api 执行错误", e);
        }
    }

    @Override
    public long analyzeTimeMillisWithNow(String cronExpression) {
        Integer[] arrStr = dataProcess(cronExpression);
        ZonedDateTime dateTime = ZonedDateTime.of(arrStr[5], arrStr[4], arrStr[3], arrStr[2], arrStr[1], arrStr[0], 0, ZoneId.systemDefault());
        long gap = dateTime.toEpochSecond() - ZonedDateTime.now().toEpochSecond();
        if (gap > 0) {
            return gap;
        }
        return 0;
    }

    private Integer[] dataProcess(String cronExpression) {
        String[] arrStr = cronExpression.split(" ");
        verify(arrStr);
        Integer[] integers = new Integer[arrStr.length];
        for (int i = 0; i < arrStr.length; i++) {
            if (!(StringsVerifyWithRegex.verifyAllNumber(arrStr[i]))) {
                if (arrStr[i].equals("*") || arrStr[i].equals("?")) {
                    if (i == 0) {
                        integers[i] = 1;
                    } else if (i == 1) {

                    } else if (i == 2) {

                    } else if (i == 3) {

                    } else if (i == 4) {

                    } else if (i == 5) {

                    }
                }
            } else {
                integers[i] = Integer.valueOf(arrStr[i]);
            }
        }
        return integers;
    }

    private void verify(String[] arrStr) {
        if (arrStr.length < 6 || arrStr.length > 7) {
            throw new CronExpressionLengthNotConform();
        }
        for (int i = 0; i < arrStr.length; i++) {
            if (!(StringsVerifyWithRegex.verifyAllNumber(arrStr[i]))) {
                if (!(arrStr[i].equals("*") || arrStr[i].equals("?"))) {
                    throw new CronExpressionNotConform();
                }
            }
        }

    }

    public static void main(String[] args) {
        System.out.println(StringsVerifyWithRegex.verifyAllNumber("1"));
        System.out.println(new RestTaskExecute().analyzeTimeMillisWithNow("1 2 4 5 6 *"));
    }
}
